﻿/** MINCONFLICT CLASS
 * Author: Preeti Francis
 * User ID : pxfranci@scotty.cs.wichita.edu
 * WSU ID: S578F746
 * Course: CS771 
 * Sem: S2014
 * 
 * Description of Class : This class is the heart of the program i.e., it contains
 * the MinConflicts algorithm that accepts a Constraint Satisfaction Problem 
 * and a maximum number of steps to either produce a solution or return null
 * if the solution is unachievable in specified number of steps.
 *
 * **/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NQueenPuzzle
{
    class MinConflict
    {
        //Returns a solution if there are no more conflicted variables left or returns null on failure or if unable to generate solution within maximum steps
        public int[,] GetSolution(ConstraintSatisfactionProblem csp, int maximumSteps)
        {
            for (int steps = 0; steps < maximumSteps; steps++)
            {
                var conflictedVariables = csp.GetRandomlyShuffledConflictedQueens();

                if (conflictedVariables.Count <= 0)
                {
                    return csp.Current;
                }

                Queen randomConflictedQueen;

                randomConflictedQueen = conflictedVariables[0];
                IList<TotalConflictsInRow> conflictValues = csp.GetConflictValuesOfRowsForSelectedQueen(randomConflictedQueen.RowPosition, randomConflictedQueen.ColumnPosition);

                int minVal = conflictValues.OrderBy(x => x.Conflicts).ToList<TotalConflictsInRow>()[0].Conflicts;


                var conflictedQueens = (from q in conflictValues
                                        where q.Conflicts == minVal
                                        select q).OrderBy(qs => qs.HashCode).ToList<TotalConflictsInRow>();

                int randomMinConflictedQueen;
                randomMinConflictedQueen = 0;

                TotalConflictsInRow randomMinConflictValue = conflictedQueens[randomMinConflictedQueen];

                ReplaceQueenWithMinPositionInCurrent(randomMinConflictValue.RowNumber, randomConflictedQueen, csp.Current);

            }
            return null;
        }

        //Moving the queen to the new position that would have minimum conflicts
        private void ReplaceQueenWithMinPositionInCurrent(int newRowPosition, Queen queen, int[,] current)
        {
            current[queen.RowPosition, queen.ColumnPosition] = 0;

            current[newRowPosition, queen.ColumnPosition] = 1;

        }
    }
}
